home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 22 / Amiga Format AFCD22 (Jan 1998, Issue 106).iso / -in_the_mag- / converters / graphics / netpbm / ppmtoinfo / ppmtoinfo.c < prev    next >
C/C++ Source or Header  |  1997-11-16  |  8KB  |  334 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <libraries/dos.h>
  4. #include <workbench/workbench.h>
  5. #include <workbench/startup.h>
  6.  
  7. #include <proto/all.h>
  8. #include <pragmas/wb_pragmas.h>
  9. #include <pragmas/exec_pragmas.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. typedef struct {
  15.     int colors;
  16.     int depth;
  17.     int max;
  18.     int red[256];
  19.     int green[256];
  20.     int blue[256];
  21. }
  22. palette;
  23.  
  24. palette *pal=NULL;              /* The palette the icon will use */
  25. char *tool=NULL;                /* The default tool of the icon */
  26. char *tooltypes[] = {           /* Tool type list. */
  27.     NULL,
  28.     NULL,
  29.     NULL,
  30.     NULL,
  31.     NULL,
  32.     NULL,
  33.     NULL,
  34.     NULL,
  35.     NULL,
  36.     NULL,
  37.     NULL
  38. };
  39. #define MAXTOOLTYPES 10
  40. int typecount=0;
  41.  
  42.  
  43. USHORT *imageData=NULL;
  44.  
  45. /* our functions */
  46. void cleanup(char *,int);
  47. BOOL makeIcon(UBYTE *, char **, char *);
  48.  
  49. int
  50. CXBRK(void)
  51. {
  52.     cleanup("User Interrupt.",21);
  53.     return (0);
  54. }                                /* Disable SAS Lattice CTRL/C handling */
  55.  
  56. struct Image iconImage1 =
  57. {
  58.     0, 0,                        /* Top Corner */
  59.     0,0,0,                         /* Width, Height, Depth */
  60.     NULL,                          /* Image Data */
  61.     0x000, 0x000,                /* PlanePick,PlaneOnOff */
  62.     NULL                        /* Next Image */
  63. };
  64.  
  65. struct DiskObject Icon =
  66. {
  67.     WB_DISKMAGIC,                    /* Magic Number */
  68.     WB_DISKVERSION,                    /* Version */
  69.     {                                /* Embedded Gadget Structure */
  70.         NULL,                        /* Next Gadget Pointer */
  71.         0, 0, 0, 0,                 /* Left,Top,Width,Height */
  72.         GADGIMAGE | GADGHBOX,        /* Flags */
  73.         GADGIMMEDIATE | RELVERIFY,    /* Activation Flags */
  74.         BOOLGADGET,                    /* Gadget Type */
  75.         &iconImage1,                   /* Render Image */
  76.         NULL,                        /* Select Image */
  77.         NULL,                        /* Gadget Text */
  78.         NULL,                        /* Mutual Exclude */
  79.         NULL,                        /* Special Info */
  80.         0,                            /* Gadget ID */
  81.         NULL                        /* User Data */
  82.     },
  83.     WBPROJECT,                        /* Icon Type */
  84.     NULL,                           /* Default Tool */
  85.     NULL,                           /* Tool Type Array */
  86.     NO_ICON_POSITION,                /* Current X */
  87.     NO_ICON_POSITION,               /* Current Y */
  88.     NULL,                            /* Drawer Structure */
  89.     NULL,                            /* Tool Window */
  90.     4000                            /* Stack Size */
  91. };
  92.  
  93. /* Opens and allocations we must clean up */
  94. struct Library *IconBase = NULL;
  95.  
  96. int
  97. log2(int val)
  98. {
  99.     int c=0;
  100.     
  101.     while(val/=2) c++;
  102.     
  103.     return c;
  104. }
  105.  
  106. #define MIN(a,b) ((a)<(b))?(a):(b);
  107.  
  108. /*
  109.  * build palette
  110.  * 
  111.  * This function reads in a ppmfile and coverts it to a "palette".
  112.  * 
  113.  * This function assumes a few things: 1. each color in the ppmfile is
  114.  * unique. 2. the ppmfile has no more than 256 pixels.  (Longer images
  115.  * are truncated.)
  116.  */
  117. palette *
  118. build_palette(char *fname)
  119. {
  120.     FILE *ppmfile;
  121.     char buf[80];
  122.     int wide, high;
  123.     int i;
  124.     palette *pal;
  125.  
  126.     pal = AllocVec(sizeof(palette), NULL);
  127.     if (!pal) 
  128.         cleanup("Could not allocate palette.",21);
  129.     
  130.     ppmfile = fopen(fname, "r");
  131.     if (!ppmfile) 
  132.         cleanup("Could not open palette file.\n",21);
  133.     
  134.     fgets(buf, 80,ppmfile);
  135.     if (strcmp(buf, "P3\n")) 
  136.         cleanup("Palette must be in P3 format.\n",21);
  137.  
  138.     fscanf(ppmfile, "%d %d", &wide, &high);
  139.     pal->colors=MIN(256,wide*high);
  140.     pal->depth=log2(pal->colors);
  141.     if ((1<<pal->depth)<pal->colors) pal->depth++;
  142.     
  143.     printf("Palette will require %d planes.\n",pal->depth);
  144.  
  145.     if (fscanf(ppmfile,"%d",&pal->max)!=1) cleanup("Failed to read palette file.\n",21);
  146.  
  147.     for(i=0;i<pal->colors;i++) 
  148.         if (fscanf(ppmfile,"%d",&pal->red[i])!=1) 
  149.             cleanup("Failed reading the palette file.\n",21);
  150.         else if (fscanf(ppmfile,"%d",&pal->green[i])!=1) 
  151.             cleanup("Failed reading the palette file.\n",21);
  152.         else if (fscanf(ppmfile,"%d",&pal->blue[i])!=1) 
  153.             cleanup("Failed reading the palette file.\n",21);
  154.  
  155.     printf("Palette:\n");
  156.     for(i=0;i<pal->colors;i++)
  157.         printf("\t%d\t%d\t%d\n",pal->red[i],pal->green[i],pal->blue[i]);
  158.            
  159.     fclose(ppmfile);
  160.     return pal;
  161. }
  162.  
  163. void 
  164. scale_palette(palette *p,int m)
  165. {
  166.     int i;
  167.     
  168.     for (i=0;i<pal->colors;i++) {
  169.         pal->red[i]=(((float)pal->red[i]/(float)p->max)*(float)m+0.5);
  170.         pal->green[i]=(((float)pal->green[i]/(float)p->max)*(float)m+0.5);
  171.         pal->blue[i]=(((float)pal->blue[i]/(float)p->max)*(float)m+0.5);
  172.     }
  173.     printf("Scaled Palette:\n");
  174.     for(i=0;i<pal->colors;i++)
  175.         printf("\t%d\t%d\t%d\n",pal->red[i],pal->green[i],pal->blue[i]);
  176.  
  177. }
  178.  
  179. int
  180. lookup_color(palette *pal,int r, int g, int b)
  181. {
  182.     int i;
  183.     
  184.     for (i=0;i<pal->colors; i++) 
  185.         if ((pal->red[i]==r)&&(pal->green[i]==g)&&(pal->blue[i]==b)) return i;
  186.  
  187.     return -1;
  188. }
  189.  
  190. void 
  191. PutPixel(USHORT *imagedata, int wwide, int high, int depth, int x, int y, int c)
  192. {
  193.     int windex, bindex, fsize;
  194.     int count;    
  195.     USHORT mask;
  196.     
  197.     windex=(wwide*y)+x/16;
  198.     fsize=wwide*high;   
  199.     bindex=x%16;
  200.  
  201.     mask=1<<(15-bindex);
  202.     
  203.     for (count=0;count<depth;count++) {
  204.         if (c&1) 
  205.             imagedata[windex]|=mask;
  206.         c/=2;
  207.         windex+=fsize;
  208.     }
  209. }
  210.     
  211. void
  212. build_image(palette *pal, struct Image *image, FILE *ppmfile)
  213. {
  214.     int wide, high, max, wwide;
  215.     char buf[80];
  216.     int x,y,c,r,g,b;
  217.     
  218.     if (!ppmfile)
  219.         cleanup("Could not open image file.\n",21);
  220.     fgets(buf,80,ppmfile);
  221.     if (strcmp(buf,"P6\n"))
  222.         cleanup("Image must be in P6 format.\n",21);
  223.         
  224.     fscanf(ppmfile,"%d",&wide); 
  225.     fscanf(ppmfile,"%d",&high);
  226.     if (!fscanf(ppmfile,"%d",&max)) cleanup("Failed to read image file.\n",21);;
  227.     
  228.     if (max!=pal->max) scale_palette(pal,max);
  229.     
  230.     /* skip to the EOL */
  231.     while (fgetc(ppmfile)!='\n') {}
  232.     
  233.     image->Width=wide; image->Height=high;
  234.     image->Depth=pal->depth;
  235.     image->PlanePick=pal->depth-1;
  236.     image->PlaneOnOff=pal->depth-1;
  237.     wwide=wide/16; if (wwide*16!=wide) wwide++;
  238.     
  239.     imageData=AllocVec(wwide*high*pal->depth*2,MEMF_CLEAR);
  240.     if (!imageData) cleanup("Could not allocate memory for the image.\n",21);
  241.  
  242.     image->ImageData=imageData;
  243.     
  244.     for(y=0;y<high;y++)
  245.         for(x=0;x<wide;x++) {
  246.             r=fgetc(ppmfile); g=fgetc(ppmfile); b=fgetc(ppmfile);
  247.             
  248.             c=lookup_color(pal,r,g,b);
  249.             if (c<0) {
  250.                 fprintf(stderr,"%d  %d  %d\n",r,g,b);
  251.                 cleanup("Image contains a color not in the palette.\n",21);
  252.             }
  253.             PutPixel(imageData,wwide,high, pal->depth,x,y,c);
  254.         }
  255.  
  256. }  
  257.  
  258. #define USAGE "syntax: ppmtoinfo [-tool {default tool}] 0[-tooltype {tool type}]10\n\t-map {mapfile} -icon {infofile} [{ppmfile}]\n"
  259.     
  260. /*
  261.  * ppmtoinfo
  262.  * 
  263.  * Arguments:   ppmfile mapfile iconfile
  264.  * 
  265.  * ppmfile - the image to turn into an icon mapfile - a ppmfile which
  266.  * describes the palette to use iconfile - the icon to make.
  267.  */
  268. void 
  269. main(int argc, char **argv)
  270. {
  271.     char *ppmfile=NULL;
  272.     char *mapfile=NULL;
  273.     char *infofile=NULL;
  274.     FILE *In;
  275.     int i;
  276.         
  277.     /* parse the arguments */
  278.     for (i=1;(i<argc)&&(argv[i][0]=='-');i++) {
  279.         if (!strcmp(argv[i],"-tool")) { tool=argv[i+1]; i++; }
  280.         else if (!strcmp(argv[i],"-tooltype")) {
  281.             if (typecount<MAXTOOLTYPES) {
  282.                 tooltypes[typecount]=argv[i+1]; 
  283.                 i++; typecount++;
  284.             }
  285.         } else if (!strcmp(argv[i],"-map")) {
  286.             mapfile=argv[i+1]; i++;
  287.         } else if (!strcmp(argv[i],"-icon")) {
  288.             infofile=argv[i+1]; i++;
  289.         } else cleanup(USAGE,21);
  290.     }
  291.  
  292.     if (i>argc) cleanup(USAGE,21);
  293.  
  294.     if (i<argc) {
  295.         ppmfile=argv[i]; i++;
  296.     }
  297.  
  298.     if (!mapfile) cleanup(USAGE,21);
  299.     
  300.     if (i<argc) cleanup(USAGE,21);
  301.     
  302.     /* Open icon.library */
  303.     if (!(IconBase = OpenLibrary("icon.library", 33)))
  304.         cleanup("Could not open icon.library",21);
  305.  
  306.     pal=build_palette(mapfile);
  307.     
  308.     if (ppmfile) In=fopen(ppmfile,"r");
  309.     else In=stdin;
  310.     
  311.     build_image(pal,&iconImage1,In);
  312.  
  313.     Icon.do_Gadget.Width=iconImage1.Width;
  314.     Icon.do_Gadget.Height=iconImage1.Height;
  315.     Icon.do_DefaultTool=tool;
  316.     Icon.do_ToolTypes=tooltypes;
  317.     
  318.     PutDiskObject(infofile,&Icon);
  319.     
  320.     cleanup("Finished.",0);
  321. }
  322.  
  323. void 
  324. cleanup(char *s, int n)
  325. {
  326.     if (pal) FreeVec(pal);
  327.     if (imageData) FreeVec(imageData);
  328.     
  329.     if (IconBase)
  330.         CloseLibrary(IconBase);
  331.     puts(s);
  332.     exit(n);
  333. }
  334.